﻿//QuikOrderCondition.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Quik
{
	using System;
	using System.Runtime.Serialization;

	using Ecng.Common;
	using Ecng.ComponentModel;
	using Ecng.Serialization;

	using StockSharp.BusinessEntities;

	/// <summary>
	/// Условия стоп-цены по отношению к цене последней сделки инструмента.
	/// </summary>
	[Serializable]
	[System.Runtime.Serialization.DataContract]
	public enum QuikStopPriceConditions
	{
		/// <summary>
		/// Больше или равно.
		/// </summary>
		[EnumMember]MoreOrEqual,

		/// <summary>
		/// Меньше или равно.
		/// </summary>
		[EnumMember]LessOrEqual,
	}

	/// <summary>
	/// Типы условий заявок, специфичных для <see cref="QuikTrader"/>.
	/// </summary>
	[Serializable]
	[System.Runtime.Serialization.DataContract]
	public enum QuikOrderConditionTypes
	{
		/// <summary>
		/// Две заявки по одному и тому же инструменту, одинаковые по направленности и объему. Первая заявка типа «Стоп-лимит», вторая – лимитированная заявка.
		/// При исполнении одной из заявок вторая снимается.
		/// </summary>
		[EnumMember]LinkedOrder,

		/// <summary>
		/// Заявка типа «Стоп-лимит», условие стоп-цены которой проверяется по одному инструменту, а в исполняемой лимитированной заявке указывается другой инструмент.
		/// </summary>
		[EnumMember]OtherSecurity,

		/// <summary>
		/// Стоп-заявка, порождающая при исполнении лимитированную заявку.
		/// </summary>
		[EnumMember]StopLimit,

		/// <summary>
		/// Заявка с условием вида «исполнить при ухудшении цены на заданную величину от достигнутого максимума (на продажу) или минимума (на покупку)».
		/// </summary>
		[EnumMember]TakeProfit,

		/// <summary>
		/// Это заявка, имеющая два условия: «тэйк-профит», если цена последней сделки после достигнутого максимума ухудшится на величину, превышающую установленный «отступ»;
		/// «стоп-лимит», если цена последней сделки ухудшится до указанного уровня.
		/// </summary>
		[EnumMember]TakeProfitStopLimit,
	}

	/// <summary>
	/// Результат исполнения заявки, специфичной для <see cref="QuikTrader"/>.
	/// </summary>
	[Serializable]
	[System.Runtime.Serialization.DataContract]
	public enum QuikOrderConditionResults
	{
		/// <summary>
		/// Заявка принята торговой системой.
		/// </summary>
		[EnumMember]
		SentToTS,

		/// <summary>
		/// Заявка отвергнута торговой системой.
		/// </summary>
		[EnumMember]
		RejectedByTS,

		/// <summary>
		/// Заявка снята пользователем.
		/// </summary>
		[EnumMember]
		Killed,

		/// <summary>
		/// Недостаточно средств клиента для выполнения заявки.
		/// </summary>
		[EnumMember]
		LimitControlFailed,

		/// <summary>
		/// Лимитированная заявка, связанная со стоп-заявкой, была снята пользователем.
		/// </summary>
		[EnumMember]
		LinkedOrderKilled,

		/// <summary>
		/// Торговой системой была удовлетворена лимитированная заявка, связанная со стоп-заявкой.
		/// </summary>
		[EnumMember]
		LinkedOrderFilled,

		/// <summary>
		/// Условие активации не наступило. Параметр заявок типов «Тэйк-профит» и «по исполнению».
		/// </summary>
		[EnumMember]
		WaitingForActivation,

		/// <summary>
		/// Условие активации наступило, начат расчет минимума/максимума цены. Параметр заявок типов «Тэйк-профит» и «Тэйк-профит по заявке».
		/// </summary>
		[EnumMember]
		CalculateMinMax,

		/// <summary>
		/// Заявка активирована на неполный объем в результате частичного исполнения заявки-условия, начат расчет минимума/максимума цены.
		/// Параметр заявок типа «Тэйк профит по заявке» с включенным признаком «Частичное исполнение заявки учитывается».
		/// </summary>
		[EnumMember]
		CalculateMinMaxAndWaitForActivation,
	}

	/// <summary>
	/// Условие заявок (например, параметры стоп- или алго- заявков), специфичных для <see cref="QuikTrader"/>.
	/// </summary>
	[Serializable]
	[System.Runtime.Serialization.DataContract]
	public class QuikOrderCondition : OrderCondition
	{
		/// <summary>
		/// Создать <see cref="QuikOrderCondition"/>.
		/// </summary>
		public QuikOrderCondition()
		{
			Type = default(QuikOrderConditionTypes);
			LinkedOrder = null;
			LinkedOrderCancel = false;
			LinkedOrderPrice = null;
			OtherSecurity = null;
			Offset = null;
			Spread = null;
			StopPriceCondition = default(QuikStopPriceConditions);
			StopPrice = null;
			StopLimitPrice = null;
			ActiveTime = null;
			IsMarketStopLimit = null;
			IsMarketTakeProfit = null;
			ConditionOrder = null;
			ConditionOrderPartiallyMatched = null;
			ConditionOrderUseMatchedBalance = null;
			Result = null;
		}

		/// <summary>
		/// Тип стоп-заявки.
		/// </summary>
		[DataMember]
		public QuikOrderConditionTypes Type
		{
			get { return (QuikOrderConditionTypes)Parameters["Type"]; }
			set { Parameters["Type"] = value; }
		}


		///<summary>
		/// Результат исполнения стоп-заявки.
		///</summary>
		/// <remarks>
		/// Значение null означает, что условие стоп-заявки ещё не сработало - стоп-заявка активна.
		/// </remarks>
		[DataMember]
		public QuikOrderConditionResults? Result
		{
			get { return (QuikOrderConditionResults?)Parameters["Result"]; }
			set { Parameters["Result"] = value; }
		}

		/// <summary>
		/// Стоп-заявка с условием по другому инструменту.
		/// </summary>
		[DataMember]
		public Security OtherSecurity
		{
			get { return (Security)Parameters["OtherSecurity"]; }
			set { Parameters["OtherSecurity"] = value; }
		}

		/// <summary>
		/// Условие стоп-цены. Используется для заявок типа «Стоп-цена по другой бумаге».
		/// </summary>
		[DataMember]
		public QuikStopPriceConditions StopPriceCondition
		{
			get { return (QuikStopPriceConditions)Parameters["StopPriceCondition"]; }
			set { Parameters["StopPriceCondition"] = value; }
		}

		/// <summary>
		/// Стоп цена, которая задает условие срабатывания стоп-заявки. Например, для заявок типа «Стоп-цена по другой бумаге» условие имеет вид:
		/// «Если цена &lt;=» (или «&gt;=») и означает исполнение заявки, если цена последней сделки по другому инструменту пересечет указанное значение.
		/// </summary>
		[DataMember]
		[Nullable]
		public decimal? StopPrice
		{
			get { return (decimal?)Parameters["StopPrice"]; }
			set { Parameters["StopPrice"] = value; }
		}

		/// <summary>
		/// Cтоп-лимит цена. Аналогична <see cref="StopPrice"/>, но используется только при типе заявки «Тэйк-профит и стоп-лимит».
		/// </summary>
		[DataMember]
		[Nullable]
		public decimal? StopLimitPrice
		{
			get { return (decimal?)Parameters["StopLimitPrice"]; }
			set { Parameters["StopLimitPrice"] = value; }
		}

		/// <summary>
		/// Признак исполнения заявки «Стоп-лимит» по рыночной цене.
		/// </summary>
		[DataMember]
		[Nullable]
		public bool? IsMarketStopLimit
		{
			get { return (bool?)Parameters["IsMarketStopLimit"]; }
			set { Parameters["IsMarketStopLimit"] = value; }
		}

		/// <summary>
		/// Время проверки условий заявки только в течение заданного периода времени (если значение null, то не проверять).
		/// Используется для заявок типов «Тэйк-профит и стоп-лимит» и «Тэйк-профит и стоп-лимит по заявке».
		/// </summary>
		[DataMember]
		public Range<DateTime> ActiveTime
		{
			get { return (Range<DateTime>)Parameters["ActiveTime"]; }
			set { Parameters["ActiveTime"] = value; }
		}

		/// <summary>
		/// Условная заявка по исполнению.
		/// </summary>
		[DataMember]
		public Order ConditionOrder
		{
			get { return (Order)Parameters["ConditionOrder"]; }
			set { Parameters["ConditionOrder"] = value; }
		}

		/// <summary>
		/// Частичное исполнение заявки учитывается. Заявка «по исполнению» будет активирована при частичном исполнении заявки-условия <see cref="ConditionOrder"/>.
		/// Если false (или null), то заявка «по исполнению» активируется только при полном исполнении заявки-условия <see cref="ConditionOrder"/>. 
		/// </summary>
		[DataMember]
		[Nullable]
		public bool? ConditionOrderPartiallyMatched
		{
			get { return (bool?)Parameters["ConditionOrderPartiallyMatched"]; }
			set { Parameters["ConditionOrderPartiallyMatched"] = value; }
		}

		/// <summary>
		/// Брать исполненный объем заявки в качестве количества выставляемой стоп-заявки. В качестве количества бумаг в заявке «по исполнению»
		/// принимается исполненный объем заявки-условия <see cref="ConditionOrder"/>. Если false (или null), то объем заявки указывается явно в свойство <see cref="Order.Volume"/>.
		/// </summary>
		[DataMember]
		[Nullable]
		public bool? ConditionOrderUseMatchedBalance
		{
			get { return (bool?)Parameters["ConditionOrderUseMatchedBalance"]; }
			set { Parameters["ConditionOrderUseMatchedBalance"] = value; }
		}

		/// <summary>
		/// Связанная лимитированная заявка.
		/// </summary>
		[DataMember]
		public Order LinkedOrder
		{
			get { return (Order)Parameters["LinkedOrder"]; }
			set { Parameters["LinkedOrder"] = value; }
		}

		/// <summary>
		/// Цена связанной лимитированной заявки.
		/// </summary>
		[DataMember]
		[Nullable]
		public decimal? LinkedOrderPrice
		{
			get { return (decimal?)Parameters["LinkedOrderPrice"]; }
			set { Parameters["LinkedOrderPrice"] = value; }
		}

		/// <summary>
		/// Признак снятия стоп-заявки при частичном исполнении связанной лимитированной заявки.
		/// </summary>
		[DataMember]
		public bool LinkedOrderCancel
		{
			get { return (bool)Parameters["LinkedOrderCancel"]; }
			set { Parameters["LinkedOrderCancel"] = value; }
		}

		/// <summary>
		/// Величина отступа от максимума (минимума) цены последней сделки.
		/// </summary>
		[DataMember]
		public Unit Offset
		{
			get { return (Unit)Parameters["Offset"]; }
			set { Parameters["Offset"] = value; }
		}

		/// <summary>
		/// Величина защитного спрэда.
		/// </summary>
		[DataMember]
		public Unit Spread
		{
			get { return (Unit)Parameters["Spread"]; }
			set { Parameters["Spread"] = value; }
		}

		/// <summary>
		/// Признак исполнения заявки «Тэйк-профит» по рыночной цене.
		/// </summary>
		[DataMember]
		[Nullable]
		public bool? IsMarketTakeProfit
		{
			get { return (bool?)Parameters["IsMarketTakeProfit"]; }
			set { Parameters["IsMarketTakeProfit"] = value; }
		}

		/// <summary>
		/// Создать копию условия (копирование параметров условия).
		/// </summary>
		/// <returns>Копия условия.</returns>
		public override OrderCondition Clone()
		{
			var clone = (QuikOrderCondition)base.Clone();
			clone.Offset = Offset.CloneNullable();
			clone.Spread = Spread.CloneNullable();
			clone.ActiveTime = ActiveTime.CloneNullable();
			return clone;
		}
	}
}